import axios from 'axios';
import { ref } from 'vue';
import useUserStore from '@/stores/user.js';

// 请求配置
const config = {
	baseURL: import.meta.env.VITE_OPEN_PROXY == "true" ? import.meta.env.VITE_APP_BASE_API : import.meta.env.VITE_APP_BASE_URL,
	timeout: 30000,
	responseType: 'json',
	headers: {
		'Content-Type': 'application/json;charset=utf-8'
	}
};

// 错误码映射
const ResultCode = {
	SUCCESS: 200,
	UNAUTHORIZED: 401,
	FORBIDDEN: 403,
	NOT_FOUND: 404,
	SERVER_ERROR: 500
};

const ERROR_CODE_MAP = {
	[ResultCode.UNAUTHORIZED]: '未授权',
	[ResultCode.FORBIDDEN]: '权限不足',
	[ResultCode.NOT_FOUND]: '请求的资源不存在',
	[ResultCode.SERVER_ERROR]: '服务器内部错误',
	400: '请求参数错误',
	default: '请求异常，请稍后重试'
};

// 刷新token相关状态
const isRefreshToken = ref(false);
const requestList = ref([]);
let isLogout = false;

// 创建axios实例
function createHttp(baseUrl = null, customConfig = {}) {
	return axios.create({
		baseURL: baseUrl ?? config.baseURL,
		timeout: config.timeout,
		responseType: config.responseType,
		...config,
		...customConfig
	});
}

const service = createHttp();

// 统一错误提示函数
const showError = (message) => {
	console.error(message);
	// 这里可以集成消息提示组件，如 Message.error(message)
};

// 刷新token函数
const refreshToken = async () => {
	const userStore = useUserStore();

	if (!userStore.getRefreshToken) {
		console.error('没有刷新token，需要重新登录');
		userStore.logout();
		throw new Error('需要重新登录');
	}

	try {
		const refreshInstance = createHttp(null, {
			headers: {
				'Authorization': `Bearer ${userStore.getRefreshToken}`
			}
		});

		const response = await refreshInstance.post('/admin/passport/refresh');

		if (response.data && response.data.code === ResultCode.SUCCESS) {
			const tokenData = response.data.data;
			userStore.setTokenInfo(tokenData);
			console.log('Token刷新成功');
			return tokenData;
		} else {
			throw new Error(response.data?.message || 'Token刷新失败');
		}
	} catch (error) {
		console.error('Token刷新失败:', error);
		userStore.logout();
		throw error;
	}
};

// 处理登出逻辑
const handleLogout = async (message = '登录已过期') => {
	if (isLogout === false) {
		isLogout = true;
		setTimeout(() => isLogout = false, 5000);
		showError(message);
		await useUserStore().logout();
	}
};

// 请求拦截器
service.interceptors.request.use(
	async config => {
		const userStore = useUserStore();
		// 添加token到请求头
		if (userStore.isLogin && config.headers) {
			config.headers = Object.assign({
				'Authorization': `Bearer ${userStore.getToken}`
			}, config.headers);
		}
		return config;
	},
	error => Promise.reject(error)
);

// 响应拦截器
service.interceptors.response.use(
	async response => {
		const userStore = useUserStore();
		const config = response.config;

		// 处理文件下载响应
		if (response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') {
			// 处理 JSON 格式的错误响应
			if (response.data instanceof Blob && response.data.type === 'application/json') {
				return new Promise((resolve, reject) => {
					const reader = new FileReader();
					reader.onload = () => {
						const result = JSON.parse(reader.result);
						if (result.code !== ResultCode.SUCCESS) {
							showError(result.message || '下载失败');
							reject(result);
						}
					};
					reader.readAsText(response.data);
				});
			}

			// 正常的文件下载响应
			const disposition = response.headers['content-disposition'];
			let fileName = '未命名文件';
			if (disposition) {
				const match = disposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
				if (match && match[1]) {
					fileName = decodeURIComponent(match[1].replace(/['"]/g, ''));
				}
			}

			return Promise.resolve({
				data: response.data,
				fileName,
				headers: response.headers
			});
		}

		// 返回完整响应
		if (config?.params?.all) {
			return response.data;
		}

		const { data } = response;
		const code = data?.code ?? ResultCode.SUCCESS;

		if (code === ResultCode.SUCCESS) {
			return data.data;
		} else {
			switch (code) {
				case ResultCode.UNAUTHORIZED:
					{
						// 检查token是否需要刷新
						if (userStore.isLogin && !isRefreshToken.value) {
							isRefreshToken.value = true;

							if (!userStore.getRefreshToken) {
								await handleLogout();
								break;
							}

							try {
								const newData = await refreshToken();

								const newToken = newData.access_token;
								// 更新当前请求的token
								config.headers.Authorization = `Bearer ${newToken}`;

								// 执行队列中的所有请求
								requestList.value.forEach(callback => callback());
								requestList.value = [];

							} catch (error) {
								console.log("刷新失败，清空队列并登出", error);

								// 刷新失败，清空队列并登出
								requestList.value.forEach(callback => callback());
								await handleLogout();
								break;
							} finally {
								requestList.value = [];
								isRefreshToken.value = false;
							}

							// 重新执行当前请求
							return service(config);
						} else {
							// 如果正在刷新token，将请求加入队列
							return new Promise((resolve) => {
								requestList.value.push(() => {
									config.headers.Authorization = `Bearer ${userStore.getToken}`;
									resolve(service(config));
								});
							});
						}
					}
					break;
				case ResultCode.FORBIDDEN:
					showError(data?.message ?? '权限不足');
					break;
				default:
					showError(data?.message || ERROR_CODE_MAP[code] || ERROR_CODE_MAP.default);
					break;
			}

			return Promise.reject(data);
		}
	},
	async error => {
		// 处理网络错误
		if (error?.message?.includes('timeout')) {
			showError('请求超时，请重试');
			return Promise.reject('timeout');
		}

		// 处理HTTP状态码错误
		if (error?.response?.status === 500) {
			showError('服务器错误');
		} else {
			const responseData = error?.response?.data;
			const errorMessage = responseData?.message || ERROR_CODE_MAP[error?.response?.status] || ERROR_CODE_MAP.default;
			showError(errorMessage);
		}

		return Promise.reject(error);
	}
);

// 请求方法封装
const request = {
	get: (url, params = {}, config = {}) => {
		return service({ url, method: 'get', params, ...config });
	},

	post: (url, data = {}, config = {}) => {
		return service({ url, method: 'post', data, ...config });
	},

	put: (url, data = {}, config = {}) => {
		return service({ url, method: 'put', data, ...config });
	},

	delete: (url, params = {}, config = {}) => {
		return service({ url, method: 'delete', params, ...config });
	},

	// 手动刷新token
	refreshToken: refreshToken,

	// 创建新的http实例
	createHttp: createHttp
};

export default request;
